package com.winning.vsts.merge.service.event;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.common.base.Joiner;
import com.google.common.eventbus.Subscribe;
import com.winning.vsts.merge.service.configuration.VstsContext;
import com.winning.vsts.merge.service.domain.VstsProject;
import com.winning.vsts.merge.service.entity.PullRequestDO;
import com.winning.vsts.merge.service.entity.WorkItemDO;
import com.winning.vsts.merge.service.service.VstsClient;
import com.winning.vsts.merge.service.service.WorksItemService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 工作项事件
 *
 * @author xcl <xcl@winning.com.cn>
 * @date 2021/11/17
 */
public class WorksItemEvent {


    private static final Logger logger = LoggerFactory.getLogger(WorksItemEvent.class);


    private final VstsContext vstsContext;

    private final VstsClient vstsClient;

    public WorksItemEvent(VstsContext vstsContext, VstsClient vstsClient) {
        this.vstsContext = vstsContext;
        this.vstsClient = vstsClient;
    }

    @Subscribe
    public void getWorkItem(PullRequestDO pullRequest) {
        VstsProject vstsProject = pullRequest.getVstsProject();
        Set<String> worksItemIds = pullRequest.getWorksItemIds();
        logger.info("=======================开始处理项目{}工作项=====================", vstsProject.getProjectName());
        List<WorkItemDO> workItemdos = worksItemIds.parallelStream().map(workItemId -> {
            try {
                RestTemplate restTemplate = vstsContext.restTemplate(vstsProject);
                JSONObject jsonObject = vstsClient.getWorkItem(restTemplate, workItemId);
                getWorkItemParent(restTemplate, jsonObject);
                WorkItemDO workItemDO = getData(jsonObject);
                workItemDO.setProjectId(vstsProject.getProjectId());
                workItemDO.setProjectName(vstsProject.getProjectName());
                workItemDO.setPullNo(pullRequest.getPullNo());
                return workItemDO;

            } catch (Exception e) {
                logger.error("项目:{}获取工作项:{} 内容错误：{}", vstsProject.getProjectName(), workItemId, e.getMessage());
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(workItemdos)) {
            logger.error("工作项：{}未获取到工作项信息", Joiner.on(", ").join(worksItemIds));
            return;
        }
        WorksItemService instance = vstsContext.getInstance(vstsProject.getProjectSoa(), WorksItemService.class);
        instance.saveRequestItem(workItemdos);
        logger.info("=======================处理项目{}工作项完成=====================", vstsProject.getProjectName());
    }

    private void getWorkItemParent(RestTemplate restTemplate, JSONObject jsonObject) {
        JSONObject fields = jsonObject.getJSONObject("fields");
        if (!StringUtils.equals("任务", fields.getString("System.WorkItemType"))) {
            return;
        }
        // 获取对应的需求工作项
        getNeedWorkItem(restTemplate, jsonObject);
    }

    private void getNeedWorkItem(RestTemplate restTemplate, JSONObject jsonObject) {
        List<JSONObject> relations = jsonObject.getObject("relations", new TypeReference<List<JSONObject>>() {
        });
        Optional<JSONObject> rel = relations.stream()
            .filter(item -> StringUtils.equals("System.LinkTypes.Hierarchy-Reverse", item.getString("rel")))
            .findAny();
        if (!rel.isPresent()) {
            return;
        }
        String[] urls = rel.get().getString("url").split("/");
        String needWorkItem = urls[urls.length - 1];
        JSONObject needJsonObject = vstsClient.getWorkItem(restTemplate, needWorkItem);
        getWorkItemParent(restTemplate, needJsonObject);
        JSONObject fields = needJsonObject.getJSONObject("fields");
        jsonObject.put("need.id", needJsonObject.getString("id"));
        jsonObject.put("need.Title", fields.getString("System.Title"));
        jsonObject.put("need.IterationPath", fields.getString("System.IterationPath"));
        jsonObject.put("need.ResolvedBy", fields.getString("Microsoft.VSTS.Common.ResolvedBy"));
        jsonObject.put("need.ResolvedDate", fields.getString("Microsoft.VSTS.Common.ResolvedDate"));
        jsonObject.put("need.AssignedTo", fields.getString("System.AssignedTo"));
        jsonObject.put("need.state", fields.getString("System.State"));
        jsonObject.put("need.type", fields.getString("System.WorkItemType"));
        JSONObject links = jsonObject.getJSONObject("_links");
        JSONObject html = links.getJSONObject("html");
        jsonObject.put("need.url", html.getString("href"));
    }


    private WorkItemDO getData(JSONObject jsonObject) {
        JSONObject fields = jsonObject.getJSONObject("fields");
        WorkItemDO workItemDO = new WorkItemDO();
        // 任务信息
        workItemDO.setItemId(jsonObject.getString("id"));
        workItemDO.setItemName(fields.getString("System.Title"));
        workItemDO.setItemStatus(fields.getString("System.State"));
        workItemDO.setItemType(fields.getString("System.WorkItemType"));
        workItemDO.setIterationNo(fields.getString("System.IterationPath"));
        workItemDO.setItemSolver(getAuthor(fields.getString("Microsoft.VSTS.Common.ResolvedBy")));
        workItemDO.setItemSolverDate(fields.getString("Microsoft.VSTS.Common.ResolvedDate"));
        workItemDO.setItemAssigner(getAuthor(fields.getString("System.AssignedTo")));
        JSONObject links = jsonObject.getJSONObject("_links");
        JSONObject html = links.getJSONObject("html");
        workItemDO.setItemUrl(html.getString("href"));
        // 需求信息
        String iterationPath = jsonObject.getString("need.IterationPath");
        if (StringUtils.isNotEmpty(iterationPath)) {
            workItemDO.setIterationNo(iterationPath);
        }
        workItemDO.setRequestId(jsonObject.getString("need.id"));
        workItemDO.setRequestName(jsonObject.getString("need.Title"));
        workItemDO.setRequestType(jsonObject.getString("need.type"));
        workItemDO.setRequestStatus(jsonObject.getString("need.state"));
        workItemDO.setRequestAssigner(getAuthor(jsonObject.getString("need.AssignedTo")));
        workItemDO.setRequestSolver(getAuthor(jsonObject.getString("need.ResolvedBy")));
        workItemDO.setRequestSolverDate(jsonObject.getString("need.ResolvedDate"));
        workItemDO.setRequestUrl(jsonObject.getString("need.url"));
        return workItemDO;
    }


    private String getAuthor(String data) {
        if (StringUtils.isEmpty(data)) {
            return null;
        }
        int index = data.indexOf("<WINNING");
        if (index <= 0) {
            return data;
        }
        return data.substring(0, index);
    }
}
